﻿using Moq;
using System.Web.Mvc;
using Stimulus360.Services;
using Stimulus360.Models.Data;
using System.Collections.Generic;
using Stimulus360.Tests.Repositories;
using Stimulus360.Controllers.Projects;
using Microsoft.VisualStudio.TestTools.UnitTesting;

namespace Stimulus360.Tests.Controllers
{   
    /// <summary>
    ///    This class contains test methods to test the Projects Controller
    /// </summary>
    [TestClass]
    public class ProjectsControllerTest
    {
        private TestContext _testContextInstance;

        /// <summary>
        ///     Gets or sets the test context which provides
        ///     information about and functionality for the current test run.
        /// </summary>
        public TestContext TestContext
        {
            get
            {
                return _testContextInstance;
            }
            set
            {
                _testContextInstance = value;
            }
        }

        /// <summary>
        ///     Method to create  dependency injected Project Controller
        /// </summary>
        /// <returns>
        ///     Project Controller with a Services injected with fake repository
        /// </returns>
        private static ProjectsController  CreateProjectsController()
        {
            List<Project > testProjects = FakeData.CreateProjects() ;
            var repository = new FakeDataRepository(null, testProjects );
            ProjectService projectService = new ProjectService(repository,null);
            InvestmentCategoryService investmentService = new InvestmentCategoryService(repository);
            ProjectsController controller = new ProjectsController(null,projectService, investmentService);
            return controller;
        }

        /// <summary>
        ///     Method to create a dependency injected Project Controller with the HTTPContext user
        ///     and authorization set.
        /// </summary>
        /// <param name="userName">
        ///     The username to set in the HTTP context
        /// </param>
        /// <returns>
        ///     Dependency injected Project Controller with the HTTPContext user
        ///     and authorization set.
        /// </returns>
        private static ProjectsController  CreateProjectControllerAs(string userName)
        {

            var mock = new Mock<ControllerContext>();
            mock.SetupGet(p => p.HttpContext.User.Identity.Name).Returns(userName);
            mock.SetupGet(p => p.HttpContext.Request.IsAuthenticated).Returns(true);

            var controller = CreateProjectsController() ;
            controller.ControllerContext = mock.Object;

            return controller;
        }

        /// <summary>
        ///     Test method to get the list of projects related to a given project
        /// </summary>
        [TestMethod]
        public void RelatedProjectsTest()
        {
            ProjectsController target = CreateProjectsController(); 
            const int projectId = 1; 
            var result = (ViewResult)target.Details(projectId);
            Assert.IsInstanceOfType(result.ViewData.Model, typeof(ProjectDetailViewModel ));
            ProjectDetailViewModel model = (ProjectDetailViewModel)result.ViewData.Model;
            int catId = model.Project.CategoryId;
            bool categoryMatches = true;
            foreach (Project project in model.RelatedProjects  )
            {
                if(project.CategoryId !=catId )
                {
                    categoryMatches = false;
                }
            }
            Assert.IsTrue(categoryMatches);
        }
    }
}